﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using InterLinq.Client;
using InterLinq.Views;
using Sebarf.Core;
using Sebarf.Core.Interfaces;
using Sebarf.Diagnostics.Interfaces;
using Sebarf.Security.UserPassword.Interfaces;
using Sebastof.Services.Interfaces;
using Shared;
using Shared.DataObjects;
using Shared.Handler;

#endregion

namespace Client {
	internal class Program {
		[STAThread]
		private static void Main() {
			Logger.WriteInformation("Start client");

			try {
				// create the interlinq client and connect to the server
				// whereas the server stores multiple cars and persons
				IClient client;
				ClientContext ctx;
				IServiceLocatorService serviceLocator;

				InterLinqClientFactory.CreateSebarfClientForInterlinq("RequestHandlerConfiguration.Client.xml",
																	   "LINQServicesFull.Profile.Server.xml",
																	   "LINQServicesFull.Profile.Client.xml",
																	   "Client with id:" + Guid.NewGuid(),
																	   "net.tcp://localhost:9876/InterLinqService", out client,
																	   out ctx, out serviceLocator);

				// authenticate
				serviceLocator.GetRegisteredService<IUsernamePasswordAuthenticationService>().Authenticate("Administrator",
																											 "Hallo");

				#region simple query

				// get all products and cars and print them out
				IQueryable<Person> persons = from p in ctx.GetData<Person>() select p;
				IQueryable<Car> cars = from c in ctx.GetData<Car>() select c;

				foreach (Person person in persons) {
					Logger.WriteInformation(person.Name);
				}

				foreach (Car car in cars) {
					Logger.WriteInformation(car.Name);
				}

				#endregion

				#region view

				// get a generic view of cars and their owner
				IEnumerable<CarsAndtheirOwnerView> typedResult = (from c in ctx.GetData<Car>()
																  join p in ctx.GetData<Person>() on c.OwnedByPerson equals p.Name
																  select
																	new GenericView(
																	new InternalData(c, "Name as CarName"),
																	new InternalData(p, "Name as PersonName"))).ToArray().
					AsTypedCollectionOf<CarsAndtheirOwnerView>();

				// print view
				foreach (CarsAndtheirOwnerView viewEntry in typedResult) {
					Logger.WriteInformation(viewEntry.CarName + " is owned by " + viewEntry.PersonName);
				}

				#endregion

				#region save data

				// change data
				foreach (CarsAndtheirOwnerView viewEntry in typedResult) {
					viewEntry.CarName = new String(viewEntry.CarName.ToCharArray().Reverse().ToArray());
				}

				// save data
				serviceLocator.GetRegisteredService<IChangeHandlerService>().SubmitChanges();

				#endregion

				#region do a multiplier request which demonstrates the extensibility of the sebarf framework

				// do a new MultiplyRequest, let the server engine process this request
				double resultOfMultiplyRequest =
					Convert.ToDouble(client.Process(new MultiplyRequest { Number1 = 100, Number2 = 200 }));
				// result should be 100*200;
				Console.WriteLine("result of the server for: 100 * 200 is :" + resultOfMultiplyRequest);

				// if we would to do this locally, we could register MultiplyRequestHandler also localy
				serviceLocator.GetRegisteredService<IAddRequestHandlerService>().AddAddionalHandler(new MultiplyRequestHandler());

				// and do the request localy
				resultOfMultiplyRequest = Convert.ToDouble(client.ProcessLocal(new MultiplyRequest { Number1 = 100, Number2 = 200 }));

				// result should be also 100*200;
				Console.WriteLine("result of the client for: 100 * 200 is also: " + resultOfMultiplyRequest);

				#endregion

				new CloseDialog("Client").ShowDialog();
			}
			catch (Exception ex) {
				Logger.WriteDebug(ex.Message + " " + ex.StackTrace);
				Console.ReadLine();
			}
		}
	}
}